/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.lucava.boatskeeper.client.control;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import java.util.List;
import org.lucava.boatskeeper.client.event.boat.BoatHandler;
import org.lucava.boatskeeper.client.event.boat.CancelEditBoatEvent;
import org.lucava.boatskeeper.client.event.boat.DeleteBoatsEvent;
import org.lucava.boatskeeper.client.event.boat.EditBoatEvent;
import org.lucava.boatskeeper.client.event.boat.ListBoatsEvent;
import org.lucava.boatskeeper.client.event.boat.ListUserBoatsEvent;
import org.lucava.boatskeeper.client.event.boat.SaveBoatEvent;
import org.lucava.boatskeeper.client.service.BoatService;
import org.lucava.boatskeeper.client.service.BoatServiceAsync;
import org.lucava.boatskeeper.client.service.CategoryService;
import org.lucava.boatskeeper.client.service.CategoryServiceAsync;
import org.lucava.boatskeeper.client.view.BoatEditView;
import org.lucava.boatskeeper.client.view.BoatListView;
import org.lucava.boatskeeper.shared.dto.BoatDto;
import org.lucava.boatskeeper.shared.dto.CategoryDto;
import org.lucava.lib.client.control.Control;

/**
 *
 * @author glenn
 */
public class BoatController extends Control implements BoatHandler {

    private BoatListView boatListView;
    private BoatEditView boatEditView;
    private BoatServiceAsync boatService = GWT.create(BoatService.class);
    private CategoryServiceAsync categoryService = GWT.create(CategoryService.class);


    @Override
    public void onInit() {
    }

    @Override
    public void onInitHandlers() {
        getEventBus().addHandler(EditBoatEvent.TYPE, BoatController.this);
        getEventBus().addHandler(SaveBoatEvent.TYPE, BoatController.this);
        getEventBus().addHandler(CancelEditBoatEvent.TYPE, BoatController.this);
        getEventBus().addHandler(DeleteBoatsEvent.TYPE, BoatController.this);
        getEventBus().addHandler(ListBoatsEvent.TYPE, BoatController.this);
        getEventBus().addHandler(ListUserBoatsEvent.TYPE, BoatController.this);
    }

    @Override
    public void onSaveBoat(SaveBoatEvent event) {

        if (boatEditView.isValid()) {
            boatService.saveBoat(boatEditView.getBoat(), new AsyncCallback<Boolean>() {
                @Override
                public void onSuccess(Boolean result) {
                    getEventBus().fireEvent(new ListBoatsEvent());
                }

                @Override
                public void onFailure(Throwable caught) {
                }
            });
        }
    }

    @Override
    public void onEditBoat(EditBoatEvent event) {
        fetchCategories();
        boatEditView = new BoatEditView(getEventBus());

        if (event.getId() != null) {
            boatService.getBoat(event.getId(), new AsyncCallback<BoatDto>() {
                @Override
                public void onSuccess(BoatDto result) {
                    boatEditView.setBoat(result);
                    assignView("content", boatEditView);
                }

                @Override
                public void onFailure(Throwable caught) {
                    Window.alert("Impossible de récupérer le bateau\n ->" + caught.getLocalizedMessage());
                }
            });
        } else {
            boatEditView.setBoat(new BoatDto());
            assignView("content", boatEditView);
        }
    }

    @Override
    public void onCancelEditBoat(CancelEditBoatEvent event) {
        assignView("content", boatListView);

    }

    @Override
    public void onDeleteBoats(DeleteBoatsEvent event) {

        boatService.removeBoats(event.getBoatIds(), new AsyncCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean result) {
                fetchBoats();
            }

            @Override
            public void onFailure(Throwable caught) {
                Window.alert("Impossible de supprimer les bateaux\n ->" + caught.getLocalizedMessage());
            }
        });

    }

    private void fetchBoats() {
        boatService.getBoats(new AsyncCallback<List<BoatDto>>() {
            @Override
            public void onSuccess(List<BoatDto> result) {
                boatListView.setBoats(result);
            }

            @Override
            public void onFailure(Throwable caught) {
                Window.alert("Impossible de récupérer les bateaux\n ->" + caught.getLocalizedMessage());
            }
        });
    }

    private void fetchCategories() {
        categoryService.getCategories(new AsyncCallback<List<CategoryDto>>() {
            @Override
            public void onSuccess(List<CategoryDto> result) {
                boatEditView.setCategories(result);
            }

            @Override
            public void onFailure(Throwable caught) {
                Window.alert("Impossible de récupérer les catégories des bateaux\n ->" + caught.getLocalizedMessage());
            }
        });
    }

    @Override
    public void onListBoats(ListBoatsEvent aThis) {
        boatListView = new BoatListView(getEventBus());
        fetchBoats();
        assignView("content", boatListView);
    }

    @Override
    public void onListUserBoats(ListUserBoatsEvent aThis) {
        //TODO other request
        assignView("content", boatListView);
    }


}
